﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace YawetagLib.Linq.Expressions
{
    public static class Extensions
    {
        private static Expression<T> Compose<T>(this Expression<T> lambda1, Expression<T> lambda2, Func<Expression, Expression, Expression> mergeExpression)
        {
            IDictionary<ParameterExpression, ParameterExpression> map = lambda1.Parameters
                .Select((l1, index) => new { l1, s = lambda2.Parameters[index] })
                .ToDictionary(p => p.s, p => p.l1);

            Expression lambda2Body = ParameterRebinder.ReplaceParameters(lambda2.Body, map);

            return Expression.Lambda<T>(mergeExpression(lambda1.Body, lambda2Body), lambda1.Parameters);
        }

        public static Expression<T> AndAlso<T>(this Expression<T> lambda1, Expression<T> lambda2)
        {
            return lambda1.Compose(lambda2, Expression.AndAlso);
        }

        public static Expression<T> OrElse<T>(this Expression<T> lambda1, Expression<T> lambda2)
        {
            return lambda1.Compose(lambda2, Expression.OrElse);
        }
    }
}
